
#include <iostream>
#include "Intaddr.h"
#include "Log.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// 使用方式: ./client ip port
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cerr << "使用方式错误,正确调用方式 ./client ip port" << std::endl;
        exit(-1);
    }
    int udp_id = socket(AF_INET, SOCK_DGRAM, 0);
    zmh::Intaddr serve_addr(AF_INET, std::string(argv[1]), std::stoi(argv[2]));

    while (true)
    {
        // 发送数据
        std::cout << "PLEASE ENTER INFOR FOR SEND:";
        std::string mes;
        std::cin >> mes;
        if (sendto(udp_id, mes.c_str(), mes.size(), 0, (struct sockaddr *)&serve_addr.Addr(), sizeof(serve_addr.Addr())) == -1)
        {
            LOG(zmh::LogLevel::ERROR) << "send mistake:" << strerror(errno);
            exit(errno);
        }
        // 接受数据
        char buffer[1024] = {0};
        struct sockaddr_in peer;
        socklen_t peerlen = sizeof(peer);
        int n = recvfrom(udp_id, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &peerlen);
        if (n == -1)
        {
            LOG(zmh::LogLevel::ERROR) << "recvfrom mistake:" << strerror(errno);
            exit(errno);
        }
        buffer[n] = 0;
        std::cout << "serve-" << zmh::Intaddr(peer).Name() << "-say:" << buffer << std::endl;
    }

    return 0;
}

/*
    udp协议：
    1. socket获得套接字文件描述符
    2. 将自己的socket与其进行绑定 ---
       客户端不用显示bind,客户端第一次向服务器进行发消息的时候，就会操作系统就会自动bind和为其分配一个端口号
       原因1. 客户端会主动发消息
       原因2. 防止端口号冲突...
*/